package com.hospital.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hospital.entity.Department;
import com.hospital.entity.Prescription;
import com.hospital.entity.PrescriptionDetail;
import com.hospital.entity.User;
import com.hospital.mapper.PrescriptionMapper;
import com.hospital.service.DepartmentService;
import com.hospital.service.PrescriptionDetailService;
import com.hospital.service.PrescriptionService;
import com.hospital.service.UserService;
import com.hospital.util.UserContext;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 处方服务实现类
 *
 * @author Hospital Management System
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class PrescriptionServiceImpl extends ServiceImpl<PrescriptionMapper, Prescription> implements PrescriptionService {

    private final UserService userService;
    private final DepartmentService departmentService;
    private final PrescriptionDetailService prescriptionDetailService;

    @Override
    public List<Prescription> getPrescriptions(String patientName) {
        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(patientName)) {
            // 这里需要join user表查询患者姓名，简化处理
            queryWrapper.eq("deleted", 0);
        } else {
            queryWrapper.eq("deleted", 0);
        }
        return list(queryWrapper);
    }

    @Override
    public List<Prescription> getDoctorPrescriptions(String patientName) {
        Long currentDoctorId = UserContext.getCurrentUser().getId();
        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("doctor_id", currentDoctorId)
                   .eq("deleted", 0);
        
        if (StringUtils.hasText(patientName)) {
            // 这里需要join user表查询患者姓名，简化处理暂时忽略这个条件
            // 在实际项目中应该使用联表查询或者先查用户ID再查处方
        }
        
        return list(queryWrapper);
    }

    @Override
    public List<Prescription> getUserPrescriptions(Long userId) {
        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("user_id", userId)
                   .eq("deleted", 0);
        log.info("查询用户处方，用户ID: {}", userId);
        return list(queryWrapper);
    }

    @Override
    public void reviewPrescription(Long prescriptionId, Long reviewerId) {
        Prescription prescription = getById(prescriptionId);
        if (prescription != null) {
            prescription.setStatus(1); // 已审核状态
            prescription.setReviewTime(LocalDateTime.now());
            prescription.setReviewerId(reviewerId);
            updateById(prescription);
            log.info("处方审核完成，处方ID: {}, 审核医生ID: {}", prescriptionId, reviewerId);
        }
    }

    @Override
    public void dispensePrescription(Long prescriptionId, Long pharmacistId) {
        Prescription prescription = getById(prescriptionId);
        if (prescription != null) {
            prescription.setStatus(2); // 已配药状态
            prescription.setDispenseTime(LocalDateTime.now());
            prescription.setPharmacistId(pharmacistId);
            updateById(prescription);
            log.info("处方配药完成，处方ID: {}, 药师ID: {}", prescriptionId, pharmacistId);
        }
    }

    @Override
    public Map<String, Object> getPrescriptionsWithPagination(String patientName, String prescriptionNo, 
                                                              Integer status, Integer type, String prescribeDate, 
                                                              Integer page, Integer size) {
        // 创建分页对象
        Page<Prescription> pageObj = new Page<>(page, size);
        
        // 构建查询条件
        QueryWrapper<Prescription> wrapper = new QueryWrapper<>();
        wrapper.eq("deleted", 0);
        
        // 患者姓名筛选（需要先查询用户ID）
        if (StringUtils.hasText(patientName)) {
            QueryWrapper<User> userWrapper = new QueryWrapper<>();
            userWrapper.like("name", patientName).eq("role", 1); // 角色1为患者
            List<User> patients = userService.list(userWrapper);
            if (!patients.isEmpty()) {
                List<Long> patientIds = patients.stream()
                        .map(User::getId)
                        .collect(Collectors.toList());
                wrapper.in("user_id", patientIds);
            } else {
                // 如果没有找到匹配的患者，返回空结果
                Map<String, Object> emptyResult = new HashMap<>();
                emptyResult.put("list", Collections.emptyList());
                // emptyResult.put("list", List.of());
                emptyResult.put("total", 0L);
                emptyResult.put("page", page);
                emptyResult.put("size", size);
                emptyResult.put("pages", 0L);
                return emptyResult;
            }
        }
        
        // 处方编号筛选
        if (StringUtils.hasText(prescriptionNo)) {
            wrapper.like("prescription_no", prescriptionNo);
        }
        
        // 状态筛选
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        // 类型筛选
        if (type != null) {
            wrapper.eq("type", type);
        }
        
        // 开具日期筛选
        if (StringUtils.hasText(prescribeDate)) {
            LocalDate date = LocalDate.parse(prescribeDate);
            wrapper.ge("prescribe_time", date.atStartOfDay())
                   .lt("prescribe_time", date.plusDays(1).atStartOfDay());
        }
        
        // 按创建时间降序排列
        wrapper.orderByDesc("create_time");
        
        // 执行分页查询
        IPage<Prescription> pageResult = page(pageObj, wrapper);
        
        // 获取查询结果
        List<Prescription> prescriptions = pageResult.getRecords();
        
        // 填充关联信息
        fillRelatedInfo(prescriptions);
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", prescriptions);
        result.put("total", pageResult.getTotal());
        result.put("page", pageResult.getCurrent());
        result.put("size", pageResult.getSize());
        result.put("pages", pageResult.getPages());
        
        return result;
    }

    @Override
    public Map<String, Object> getDoctorPrescriptionsWithPagination(Long doctorId, String patientName, 
                                                                    String prescriptionNo, Integer status, 
                                                                    Integer type, String prescribeDate, 
                                                                    Integer page, Integer size) {
        // 创建分页对象
        Page<Prescription> pageObj = new Page<>(page, size);
        
        // 构建查询条件
        QueryWrapper<Prescription> wrapper = new QueryWrapper<>();
        wrapper.eq("doctor_id", doctorId)
               .eq("deleted", 0);
        
        // 患者姓名筛选（需要先查询用户ID）
        if (StringUtils.hasText(patientName)) {
            QueryWrapper<User> userWrapper = new QueryWrapper<>();
            userWrapper.like("name", patientName).eq("role", 1); // 角色1为患者
            List<User> patients = userService.list(userWrapper);
            if (!patients.isEmpty()) {
                List<Long> patientIds = patients.stream()
                        .map(User::getId)
                        .collect(Collectors.toList());
                wrapper.in("user_id", patientIds);
            } else {
                // 如果没有找到匹配的患者，返回空结果
                Map<String, Object> emptyResult = new HashMap<>();
                emptyResult.put("list", Collections.emptyList());
                // emptyResult.put("list", List.of())
                emptyResult.put("total", 0L);
                emptyResult.put("page", page);
                emptyResult.put("size", size);
                emptyResult.put("pages", 0L);
                return emptyResult;
            }
        }
        
        // 处方编号筛选
        if (StringUtils.hasText(prescriptionNo)) {
            wrapper.like("prescription_no", prescriptionNo);
        }
        
        // 状态筛选
        if (status != null) {
            wrapper.eq("status", status);
        }
        
        // 类型筛选
        if (type != null) {
            wrapper.eq("type", type);
        }
        
        // 开具日期筛选
        if (StringUtils.hasText(prescribeDate)) {
            LocalDate date = LocalDate.parse(prescribeDate);
            wrapper.ge("prescribe_time", date.atStartOfDay())
                   .lt("prescribe_time", date.plusDays(1).atStartOfDay());
        }
        
        // 按创建时间降序排列
        wrapper.orderByDesc("create_time");
        
        // 执行分页查询
        IPage<Prescription> pageResult = page(pageObj, wrapper);
        
        // 获取查询结果
        List<Prescription> prescriptions = pageResult.getRecords();
        
        // 填充关联信息
        fillRelatedInfo(prescriptions);
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("list", prescriptions);
        result.put("total", pageResult.getTotal());
        result.put("page", pageResult.getCurrent());
        result.put("size", pageResult.getSize());
        result.put("pages", pageResult.getPages());
        
        return result;
    }

    @Override
    public void fillRelatedInfo(Prescription prescription) {
        if (prescription == null) {
            return;
        }
        
        // 填充患者信息
        if (prescription.getUserId() != null) {
            User user = userService.getById(prescription.getUserId());
            if (user != null) {
                prescription.setUserName(user.getName());
            }
        }
        
        // 填充医生信息
        if (prescription.getDoctorId() != null) {
            User doctor = userService.getById(prescription.getDoctorId());
            if (doctor != null) {
                prescription.setDoctorName(doctor.getName());
            }
        }
        
        // 填充科室信息
        if (prescription.getDepartmentId() != null) {
            Department department = departmentService.getById(prescription.getDepartmentId());
            if (department != null) {
                prescription.setDepartmentName(department.getName());
            }
        }
        
        // 填充审核医生信息
        if (prescription.getReviewerId() != null) {
            User reviewer = userService.getById(prescription.getReviewerId());
            if (reviewer != null) {
                prescription.setReviewerName(reviewer.getName());
            }
        }
        
        // 填充配药药师信息
        if (prescription.getPharmacistId() != null) {
            User pharmacist = userService.getById(prescription.getPharmacistId());
            if (pharmacist != null) {
                prescription.setPharmacistName(pharmacist.getName());
            }
        }
    }

    @Override
    public void fillRelatedInfo(List<Prescription> prescriptions) {
        if (prescriptions == null || prescriptions.isEmpty()) {
            return;
        }

        // 获取所有用户ID、医生ID、科室ID等
        List<Long> userIds = prescriptions.stream()
                .map(Prescription::getUserId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());

        List<Long> doctorIds = prescriptions.stream()
                .map(Prescription::getDoctorId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());

        List<Long> reviewerIds = prescriptions.stream()
                .map(Prescription::getReviewerId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());

        List<Long> pharmacistIds = prescriptions.stream()
                .map(Prescription::getPharmacistId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());

        List<Long> departmentIds = prescriptions.stream()
                .map(Prescription::getDepartmentId)
                .filter(id -> id != null)
                .distinct()
                .collect(Collectors.toList());

        // 合并所有用户ID并批量查询
        List<Long> allUserIds = userIds.stream()
                .collect(Collectors.toList());
        allUserIds.addAll(doctorIds);
        allUserIds.addAll(reviewerIds);
        allUserIds.addAll(pharmacistIds);
        allUserIds = allUserIds.stream().distinct().collect(Collectors.toList());

        // 批量查询用户信息
        Map<Long, User> userMap = new HashMap<>();
        if (!allUserIds.isEmpty()) {
            List<User> users = userService.listByIds(allUserIds);
            userMap = users.stream()
                    .collect(Collectors.toMap(User::getId, user -> user));
        }

        // 批量查询科室信息
        Map<Long, Department> departmentMap = new HashMap<>();
        if (!departmentIds.isEmpty()) {
            List<Department> departments = departmentService.listByIds(departmentIds);
            departmentMap = departments.stream()
                    .collect(Collectors.toMap(Department::getId, dept -> dept));
        }

        // 填充关联信息
        final Map<Long, User> finalUserMap = userMap;
        final Map<Long, Department> finalDepartmentMap = departmentMap;
        
        prescriptions.forEach(prescription -> {
            // 填充患者姓名
            if (prescription.getUserId() != null && finalUserMap.containsKey(prescription.getUserId())) {
                User user = finalUserMap.get(prescription.getUserId());
                prescription.setUserName(user.getName());
            }

            // 填充医生姓名
            if (prescription.getDoctorId() != null && finalUserMap.containsKey(prescription.getDoctorId())) {
                User doctor = finalUserMap.get(prescription.getDoctorId());
                prescription.setDoctorName(doctor.getName());
            }

            // 填充科室名称
            if (prescription.getDepartmentId() != null && finalDepartmentMap.containsKey(prescription.getDepartmentId())) {
                Department department = finalDepartmentMap.get(prescription.getDepartmentId());
                prescription.setDepartmentName(department.getName());
            }

            // 填充审核医生姓名
            if (prescription.getReviewerId() != null && finalUserMap.containsKey(prescription.getReviewerId())) {
                User reviewer = finalUserMap.get(prescription.getReviewerId());
                prescription.setReviewerName(reviewer.getName());
            }

            // 填充配药药师姓名
            if (prescription.getPharmacistId() != null && finalUserMap.containsKey(prescription.getPharmacistId())) {
                User pharmacist = finalUserMap.get(prescription.getPharmacistId());
                prescription.setPharmacistName(pharmacist.getName());
            }
        });
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(Prescription prescription) {
        // 保存处方基本信息
        boolean success = super.save(prescription);
        if (success && prescription.getPrescriptionDetails() != null) {
            // 设置处方ID并保存明细
            prescription.getPrescriptionDetails().forEach(detail -> detail.setPrescriptionId(prescription.getId()));
            success = prescriptionDetailService.saveBatch(prescription.getPrescriptionDetails());
            
            // 计算并更新总金额
            if (success) {
                BigDecimal totalAmount = prescription.getPrescriptionDetails().stream()
                    .map(PrescriptionDetail::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                prescription.setTotalAmount(totalAmount);
                success = updateById(prescription);
            }
        }
        return success;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateById(Prescription prescription) {
        // 更新处方基本信息
        boolean success = super.updateById(prescription);
        if (success && prescription.getPrescriptionDetails() != null) {
            // 更新处方明细
            success = prescriptionDetailService.updatePrescriptionDetails(
                prescription.getId(), 
                prescription.getPrescriptionDetails()
            );
            
            // 重新计算并更新总金额
            if (success) {
                BigDecimal totalAmount = prescription.getPrescriptionDetails().stream()
                    .map(PrescriptionDetail::getAmount)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
                prescription.setTotalAmount(totalAmount);
                success = super.updateById(prescription);
            }
        }
        return success;
    }

    @Override
    public Prescription getPrescriptionDetail(Long prescriptionId) {
        // 获取处方基本信息
        Prescription prescription = this.getById(prescriptionId);
        if (prescription == null) {
            return null;
        }

        // 填充处方关联信息（患者、医生、科室等）
        this.fillRelatedInfo(prescription);
        
        // 获取处方明细列表
        List<PrescriptionDetail> details = prescriptionDetailService.getByPrescriptionId(prescriptionId);
        prescription.setPrescriptionDetails(details);

        return prescription;
    }

    @Override
    public List<Prescription> getByMedicalRecordId(Long medicalRecordId) {
        if (medicalRecordId == null) {
            return new ArrayList<>();
        }

        // 构建查询条件
        QueryWrapper<Prescription> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("medical_record_id", medicalRecordId)
                   .eq("deleted", 0)
                   .orderByDesc("create_time");

        // 查询处方列表
        List<Prescription> prescriptions = list(queryWrapper);

        // 填充关联信息
        if (!prescriptions.isEmpty()) {
            fillRelatedInfo(prescriptions);
        }

        return prescriptions;
    }
} 